﻿using System;
using System.Linq;
using System.ServiceProcess;
using System.Activities;
using Reactor.Extensions;
using Reactor.Workflow.Activities;

namespace Reactor.ServiceGrid.Workflows.Activities
{
    public sealed class ShutdownWindowsService : ReactorCodeActivityBase
    {
        [RequiredArgument]
        public InArgument<ServiceIdentifier> ServiceIdentifier { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var serviceIdentifier = context.GetValue(ServiceIdentifier);
            var serviceController = ServiceController.GetServices().SingleOrDefault(s => s.ServiceName == serviceIdentifier.ToServiceInstanceString());
            if (serviceController == null)
            {
                Log.WarnFormat(string.Format("WindowsServiceController not found for service: {0}.", serviceIdentifier.ToServiceInstanceString()));
                return;
            }

            if (Log.IsDebugEnabled) Log.DebugFormat("Attepting to stop windows service: {0}", serviceController.ServiceName);

            serviceController.Refresh();
            if (serviceController.Status == ServiceControllerStatus.Stopped || serviceController.Status == ServiceControllerStatus.StopPending)
            {
                if (Log.IsDebugEnabled) Log.DebugFormat("Windows service '{0}' is already stopped or is stopping. Skipping stop action.", serviceController.ServiceName);

                return;
            }

            string stopFailureReason;
            if (!serviceController.TryStop(TimeSpan.FromMinutes(1), out stopFailureReason))
                throw new ApplicationException(stopFailureReason);

            Log.InfoFormat("Stopped Windows service: {0}", serviceController.ServiceName);
        }
    }
}
